<?php

namespace App\Services;

use Illuminate\Support\Facades\Log;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\HttpException;

class ErrorMessageService
{
    /**
     * 获取用户友好的错误消息
     */
    public static function getFriendlyMessage(\Throwable $e): string
    {
        // 业务异常
        if ($e instanceof \App\Exceptions\BusinessException) {
            return $e->getMessage();
        }

        // 验证异常
        if ($e instanceof ValidationException) {
            return '请检查输入信息是否正确';
        }

        // HTTP异常
        if ($e instanceof HttpException) {
            return self::getHttpErrorMessage($e->getStatusCode());
        }

        // 数据库异常
        if ($e instanceof \Illuminate\Database\QueryException) {
            return self::getDatabaseErrorMessage($e);
        }

        // 文件上传异常
        if ($e instanceof \Illuminate\Http\Exceptions\PostTooLargeException) {
            return '上传文件过大，请选择较小的文件';
        }

        // 认证异常
        if ($e instanceof \Illuminate\Auth\AuthenticationException) {
            return '请先登录后再进行操作';
        }

        // 权限异常
        if ($e instanceof \Illuminate\Auth\Access\AuthorizationException) {
            return '您没有权限执行此操作';
        }

        // 默认错误消息
        return config('app.debug') 
            ? $e->getMessage() 
            : '操作失败，请稍后重试';
    }

    /**
     * 获取HTTP状态码对应的错误消息
     */
    protected static function getHttpErrorMessage(int $statusCode): string
    {
        return match($statusCode) {
            400 => '请求参数错误',
            401 => '请先登录',
            403 => '没有权限访问',
            404 => '页面不存在',
            405 => '请求方法不允许',
            408 => '请求超时',
            422 => '数据验证失败',
            429 => '请求过于频繁，请稍后再试',
            500 => '服务器内部错误',
            502 => '网关错误',
            503 => '服务暂时不可用',
            504 => '网关超时',
            default => '请求失败',
        };
    }

    /**
     * 获取数据库错误消息
     */
    protected static function getDatabaseErrorMessage(\Illuminate\Database\QueryException $e): string
    {
        $errorCode = $e->getCode();
        $errorMessage = $e->getMessage();

        // MySQL错误代码
        if (str_contains($errorMessage, 'Duplicate entry')) {
            return '数据已存在，请检查后重试';
        }

        if (str_contains($errorMessage, 'Foreign key constraint')) {
            return '数据关联错误，请检查相关数据';
        }

        if (str_contains($errorMessage, 'Connection refused')) {
            return '数据库连接失败，请稍后重试';
        }

        if (str_contains($errorMessage, 'Table') && str_contains($errorMessage, 'doesn\'t exist')) {
            return '数据表不存在，请联系管理员';
        }

        // 记录详细的数据库错误
        Log::error('Database error occurred', [
            'error_code' => $errorCode,
            'error_message' => $errorMessage,
            'sql' => $e->getSql() ?? 'N/A',
        ]);

        return '数据操作失败，请稍后重试';
    }

    /**
     * 获取验证错误消息
     */
    public static function getValidationMessages(ValidationException $e): array
    {
        $messages = [];
        $errors = $e->errors();

        foreach ($errors as $field => $fieldErrors) {
            foreach ($fieldErrors as $error) {
                $messages[$field] = self::translateValidationMessage($error);
            }
        }

        return $messages;
    }

    /**
     * 翻译验证错误消息
     */
    protected static function translateValidationMessage(string $message): string
    {
        $translations = [
            'The :attribute field is required.' => ':attribute 字段是必填的',
            'The :attribute field must be a string.' => ':attribute 字段必须是字符串',
            'The :attribute field must be an integer.' => ':attribute 字段必须是整数',
            'The :attribute field must be numeric.' => ':attribute 字段必须是数字',
            'The :attribute field must be an email.' => ':attribute 字段必须是有效的邮箱地址',
            'The :attribute field must be unique.' => ':attribute 字段必须唯一',
            'The :attribute field must be at least :min characters.' => ':attribute 字段至少需要 :min 个字符',
            'The :attribute field may not be greater than :max characters.' => ':attribute 字段不能超过 :max 个字符',
            'The :attribute field must be between :min and :max characters.' => ':attribute 字段必须在 :min 到 :max 个字符之间',
            'The :attribute field must be a valid URL.' => ':attribute 字段必须是有效的URL',
            'The :attribute field must be a valid date.' => ':attribute 字段必须是有效的日期',
            'The :attribute field must be after :date.' => ':attribute 字段必须在 :date 之后',
            'The :attribute field must be before :date.' => ':attribute 字段必须在 :date 之前',
            'The :attribute field must be accepted.' => ':attribute 字段必须被接受',
            'The :attribute field must be confirmed.' => ':attribute 字段必须确认',
            'The :attribute field must be different.' => ':attribute 字段必须不同',
            'The :attribute field must be the same.' => ':attribute 字段必须相同',
            'The :attribute field must be a file.' => ':attribute 字段必须是文件',
            'The :attribute field must be an image.' => ':attribute 字段必须是图片',
            'The :attribute field must be a valid IP address.' => ':attribute 字段必须是有效的IP地址',
            'The :attribute field must be a valid JSON string.' => ':attribute 字段必须是有效的JSON字符串',
        ];

        return $translations[$message] ?? $message;
    }

    /**
     * 获取字段名称翻译
     */
    public static function getFieldName(string $field): string
    {
        $fieldNames = [
            'name' => '姓名',
            'email' => '邮箱',
            'phone' => '电话',
            'password' => '密码',
            'password_confirmation' => '确认密码',
            'title' => '标题',
            'content' => '内容',
            'description' => '描述',
            'price' => '价格',
            'quantity' => '数量',
            'stock' => '库存',
            'category' => '分类',
            'status' => '状态',
            'type' => '类型',
            'reason' => '原因',
            'address' => '地址',
            'city' => '城市',
            'province' => '省份',
            'postal_code' => '邮政编码',
            'company' => '公司',
            'website' => '网站',
            'logo' => '标志',
            'image' => '图片',
            'file' => '文件',
            'date' => '日期',
            'time' => '时间',
            'start_date' => '开始日期',
            'end_date' => '结束日期',
        ];

        return $fieldNames[$field] ?? $field;
    }
}
